package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.exception.BusinessException;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.SetmealDishMapper;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.SetmealService;
import com.itheima.reggie.utils.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Resource
    private SetmealMapper setmealMapper;
    @Resource
    private SetmealDishMapper setmealDishMapper;
    @Resource
    private CategoryMapper categoryMapper;

    @Override
    @Transactional
    @CacheEvict(value = "setmealCache", key = "#setmealDto.categoryId")
    public Result<String> addSetmeal(SetmealDto setmealDto) {
        setmealMapper.insert(setmealDto);
        List<SetmealDish> setmealDishList = setmealDto.getSetmealDishes();
        setmealDishList =  setmealDishList.stream().peek((item) -> item.setSetmealId(setmealDto.getId())).collect(Collectors.toList());
        for (SetmealDish setmealDish : setmealDishList) {
            setmealDishMapper.insert(setmealDish);
        }
        return Result.success("新建套餐成功");
    }

    @Override
    public Result<Page<SetmealDto>> getPage(String setmealName, int currentPage, int pageSize) {
        Page<Setmeal> setmealPage = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(setmealName != null, Setmeal::getName, setmealName)
                .orderByDesc(Setmeal::getUpdateTime);
        setmealMapper.selectPage(setmealPage, queryWrapper);
        Page<SetmealDto> setmealDtoPage = new Page<>();
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");
        List<Setmeal> setmealList = setmealPage.getRecords();
        List<SetmealDto> setmealDtoList = setmealList.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);
            Long categoryId = item.getCategoryId();
            Category category = categoryMapper.selectById(categoryId);
            if (category != null) {
                setmealDto.setCategoryName(category.getName());
            }
            return setmealDto;
        }).collect(Collectors.toList());
        setmealDtoPage.setRecords(setmealDtoList);
        return Result.success(setmealDtoPage);
    }

    @Override
    @CacheEvict(value = "setmealCache", allEntries = true)
    public Result<String> deleteSetmeals(List<Long> ids) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId, ids)
                .eq(Setmeal::getStatus, 1);
        Long count = setmealMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new BusinessException("套餐正在售卖中,不能删除");
        }
        setmealMapper.deleteBatchIds(ids);
        LambdaQueryWrapper<SetmealDish> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(SetmealDish::getSetmealId, ids);
        setmealDishMapper.delete(queryWrapper1);
        return Result.success("删除套餐成功");
    }

    @Override
    @Cacheable(value = "setmealCache", key = "#setmeal.categoryId")
    public Result<List<Setmeal>> getSetmealList(Setmeal setmeal) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Setmeal::getCategoryId, setmeal.getCategoryId())
                .eq(Setmeal::getStatus, 1)
                .orderByDesc(Setmeal::getUpdateTime);
        List<Setmeal> setmealList = setmealMapper.selectList(queryWrapper);
        return Result.success(setmealList);
    }

    @Override
    public Result<String> updateSetmealStatus(List<Long> ids, int toStatus) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids);
        Setmeal setmeal = new Setmeal();
        setmeal.setStatus(toStatus);
        setmealMapper.update(setmeal,queryWrapper);
        return Result.success("套餐售卖状态更改成功");
    }

    @Override
    public Result<SetmealDto> getSetmealDtoWithId(Long id) {
        Setmeal setmeal = setmealMapper.selectById(id);
        SetmealDto setmealDto = new SetmealDto();
        BeanUtils.copyProperties(setmeal,setmealDto);
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishList = setmealDishMapper.selectList(queryWrapper);
        setmealDto.setSetmealDishes(setmealDishList);
        return Result.success(setmealDto);
    }

    @Override
    @CacheEvict(value = "setmealCache", allEntries = true)
    @Transactional
    public Result<String> updateSetmeal(SetmealDto setmealDto) {
        // 修改套餐表数据
        Setmeal setmeal  = new Setmeal();
        BeanUtils.copyProperties(setmealDto,setmeal);
        setmealMapper.updateById(setmeal);
        // 删除套餐详情表数据
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishMapper.delete(queryWrapper);
        // 添加套餐详情表数据
        List<SetmealDish> setmealDishList = setmealDto.getSetmealDishes();
        setmealDishList =  setmealDishList.stream().map((item)->{
            item.setSetmealId(setmealDto.getId());
            return item;
        }).collect(Collectors.toList());
        for (SetmealDish setmealDish : setmealDishList) {
            setmealDishMapper.insert(setmealDish);
        }
        return Result.success("套餐修改成功");
    }
}
